# -*- coding: utf-8 -*-
import datetime
from django.views.generic.simple import direct_to_template
from django.http import HttpResponseRedirect
from lr.bank.models import Bank, Transaction, BankException
from lr.settings import CONTEST_CASH_LIMIT
from lr.message.models import LrMessage
from django.template.loader import render_to_string
from lr.register.models import Profile
from lr.board.forms import ContestForm
from lr.board.models import Contest
from decimal import Decimal
import fpformat
from lr.work.models import Work, WorkRels
from django.contrib.auth.models import User
from lr.events.models import LrEvent


def board(request):
    """ Доска объявлений """
    if not request.user.is_authenticated():
        HttpResponseRedirect('/')
    
    if 'action' in request.GET:
        action = request.GET['action']
        if action == 'new':
            # Запрос на новый конкурс
            return new_contest(request)
    elif 'view' in request.GET:
        view = request.GET['view']
        return view_contest(request, view)
    elif 'start' in request.GET:
        start = request.GET['start']
        return start_contest(request, start)
    elif 'stop' in request.GET:
        stop = request.GET['stop']
        return stop_contest(request, stop)
    
    board_data = {}
    contests = Contest.objects.all().order_by('time_limit')
    board_data['contests'] = contests
    return direct_to_template(request, 'board/board.html', board_data)


def new_contest(request):
    """ Новый конкурс """
    bank = Bank.objects.get(user=request.user)
    if bank.cash < CONTEST_CASH_LIMIT:
        name, gender = Profile.get_user_name(user=request.user, profile=request.profile)
        LrMessage.objects.create_message(request.user, u'Не хватает средств', \
                                         render_to_string('messages/contest_lo_money.html', \
                                                          { 'name': name, 'gender': gender, \
                                                            'limit': CONTEST_CASH_LIMIT }))
        return HttpResponseRedirect('message')
    
    contest_person = None
    if request.method == 'POST':
        form = ContestForm(request.POST)
        if form.is_valid():
            # Создать новый конкурс
            if 'start_time' in form.cleaned_data and form.cleaned_data['start_time']:
                start_time = datetime.datetime.strptime(form.cleaned_data['start_time'], '%d.%m.%Y %H:%M')
            else:
                start_time = None
            
            if 'time_limit' in form.cleaned_data and form.cleaned_data['time_limit']:
                time_limit = datetime.datetime.strptime(form.cleaned_data['time_limit'], '%d.%m.%Y %H:%M')
            else:
                time_limit = None
            
            cash = Decimal(fpformat.fix(form.cleaned_data['cash'], 2))
            title = form.cleaned_data['title']
            
            is_personal = False
            writer = None
            if 'writer' in request.POST:
                try:
                    writer = User.objects.get(id=request.POST['writer'])
                    is_personal = True
                except:
                    pass
            try:
                # Списать с объявителя конкурса заявленную сумму
                Transaction.objects.create_transaction(cash=cash, detail=u'Конкурс "%s"' % title, sender=request.user)
                # Создать конкурс
                contest = Contest.objects.create_contest(initiator=request.user, cash=cash, title=title, theme=form.cleaned_data['theme'],
                                                         competitors_limit=form.cleaned_data['competitors_limit'],
                                                         genre=form.cleaned_data['genre'], start_time=start_time,
                                                         time_limit=time_limit, is_personal=is_personal,
                                                         for_exclusive=form.cleaned_data['for_exclusive'])
                if writer:
                    # Персональный конкурс, сразу добавляем писателя в список участников
                    contest.competitors.add(writer)
                    writer_name, writer_gender = Profile.get_user_name(user=writer)
                    name = Profile.get_user_name(user=request.user, profile=request.profile)[0]
                    LrMessage.objects.create_message(user=writer, title=u'Персональный заказ',
                                         description=render_to_string('messages/personal_commission.html',
                                                                      { 'gender': writer_gender, 'name': writer_name,
                                                                        'customer': name, 'contest': contest }))
                else:
                    # Общий конкурс
                    LrEvent.objects.create_event(render_to_string('events/new_contest.html', { 'contest': contest }))
                return HttpResponseRedirect('board')
            except BankException:
                name, gender = Profile.get_user_name(user=request.user, profile=request.profile)
                LrMessage.objects.create_message(user=request.user, title=u'Не достаточно средств',
                                     description=render_to_string('messages/has_no_money.html',
                                                                  { 'gender': gender, 'name': name }))
                return HttpResponseRedirect('message')
        elif 'writer' in request.POST:
            try:
                contest_person = User.objects.get(id=request.POST['writer'])
            except:
                contest_person = None
    else:
        form = ContestForm()
    
    contest_data = {}
    
    if 'contest_person' in request.session:
        # Заказ для конкретного писателя
        contest_person = request.session['contest_person']
        del request.session['contest_person']
    
    if contest_person:
        writer_name = Profile.get_user_name(user=contest_person)[0]
        contest_data['writer_id'] = contest_person.id
        contest_data['writer_name'] = writer_name
    
    contest_data['form'] = form
    return direct_to_template(request, 'board/board_new_contest.html', contest_data)



def view_contest(request, contest_id):
    """ Просмотр конкурса """
    try:
        contest = Contest.objects.get(id=contest_id)
    except:
        return HttpResponseRedirect('/')
    
    if request.method == 'POST':
        if 'action' in request.POST:
            action = request.POST['action']
            if action == 'join':
                # Запрсо на участие в конкурсе
                contest.competitors.add(request.user)
                work = Work.objects.createWork(author=request.user, title=u'На конкурс "%s"' % contest.title,
                                               genre=contest.genre, contest=contest)
                return HttpResponseRedirect('table?edit=%d' % work.id)
        elif 'close' in request.POST:
            # Запрос на закрытие конкурса
            return close_contest(request, request.POST['close'])
        elif 'set_winner' in request.POST:
            # Инициатор конкурса выбрал победителя
            return set_contest_winner(request, request.POST['set_winner'], request.POST.get('winner', 0))
        elif 'get_commission' in request.POST and contest.is_personal:
            # Пользователь принял или отклонил персональный заказ
            return get_comission(request.POST['get_commission'] == 'true', request, contest)
    
    is_initiator = contest.initiator == request.user
    already_joined = contest.competitors.filter(id=request.user.id).count() > 0
    status = contest.get_status()
    if status >= 0:
        can_join = not already_joined and not is_initiator and request.profile.is_writer()
    else:
        can_join = False
    
    works = Work.objects.filter(contest=contest).exclude(status=u'draft')
    initiator_name, initiator_gender = Profile.get_user_name(user=contest.initiator)
    
    if already_joined:
        try:
            my_work = Work.objects.get(contest=contest, author=request.user)
        except:
            my_work = None
    else:
        my_work = None
    
    is_finished = contest.is_finished()
    failed = False
    
    if is_initiator:
        if status < 0 and contest.competitors.count() == 0:
            # Набор завершился, но нет ни одного конкурсанта
            failed = True
        if is_finished and len(works) == 0:
            # Конкурс завершился, но нет ни одной работы
            failed = True
    
    if status < 0 and not is_finished:
        # Проверить, если все конкурсанты уже сделали свою работу,
        # не дожидаться времени завершения конкурса, а сразу обозначить его
        # как завершенный
        all_done = True
        competitors = contest.competitors.all()
        for competitor in competitors:
            if works.filter(author=competitor).count() == 0:
                all_done = False
                break
        is_finished = all_done
    
    contest_data = {}
    
    if contest.is_personal:
        # Это персональный заказ
        if contest.competitors.count() > 0:
            writer = contest.competitors.all()[0]
            name = Profile.get_user_name(user=writer)[0]
            contest_data['writer_name'] = name
            contest_data['writer_id'] = writer.id
            contest_data['im_writer'] = request.user == writer
        else:
            contest.is_personal = False
            contest.save()
    
    contest_data['works'] = works
    contest_data['can_join'] = can_join
    contest_data['is_initiator'] = is_initiator
    contest_data['initiator_name'] = initiator_name
    contest_data['initiator_gender'] = initiator_gender
    contest_data['contest'] = contest
    contest_data['is_finished'] = is_finished
    contest_data['failed'] = failed
    contest_data['my_work'] = my_work
    return direct_to_template(request, 'board/board_view.html', contest_data)



def start_contest(request, contest_id):
    """ Принудительно завершить набор конкурсантов и начать конкурс """
    try:
        contest = Contest.objects.get(id=contest_id)
        if contest.start_time:
            contest.start_time = datetime.datetime.now()
            contest.save()
            LrMessage.objects.create_message(request.user, u'Старт конкурса',
                                             u'Вы задействовали отладочную функцию принудительного старта конкурса. \
                                             Время окончания набора конкурсантов перенесено на текущий момент.<br/> \
                                             Можете <a href="board?view=%d">вернуться к конкурсу</a>.' % contest.id)
        else:
            LrMessage.objects.create_message(request.user, u'Старт конкурса',
                                             u'Вы задействовали отладочную функцию принудительного старта конкурса. \
                                             Время окончания набора конкурсантов не установлено, конкурс начнется, как только будет \
                                             набрано указанное количество конкурсантов.<br/> \
                                             Можете <a href="board?view=%d">вернуться к конкурсу</a>.' % contest.id)
        return HttpResponseRedirect('message')
    except:
        pass
    return HttpResponseRedirect('/')



def stop_contest(request, contest_id):
    """ Принудительно завершить набор конкурсантов и начать конкурс """
    try:
        contest = Contest.objects.get(id=contest_id)
        now = datetime.datetime.now()
        if contest.start_time:
            contest.start_time = now
        contest.time_limit = now
        contest.save()
        LrMessage.objects.create_message(request.user, u'Финиш конкурса',
                                         u'Вы задействовали отладочную функцию принудительного завершения конкурса. \
                                         Время окончания конкурса перенесено на текущий момент.<br/> \
                                         Можете <a href="board?view=%d">вернуться к конкурсу</a>.' % contest.id)
        return HttpResponseRedirect('message')
    except:
        pass
    return HttpResponseRedirect('/')



def close_contest(request, contest_id):
    """ Закрыть конкурс """
    try:
        contest = Contest.objects.get(id=contest_id)
    except:
        return HttpResponseRedirect('/')
    
    if contest.initiator != request.user:
        # Только инициатор конкурса может его закрывать
        return HttpResponseRedirect('/')
    
    works = Work.objects.filter(contest=contest)
    for work in works:
        work.contest = None
        work.save()
    
    Transaction.objects.create_transaction(cash=contest.cash, detail=u'Возврат призового фонда "%s"' % contest.title,
                                           recipient=contest.initiator)
    
    contest.competitors.clear()
    contest.delete()
    return HttpResponseRedirect('board')



def set_contest_winner(request, contest_id, winner_id):
    """  Выбрать победителя конкурса """
    try:
        contest = Contest.objects.get(id=contest_id)
        winner_id = int(winner_id)
    except:
        return HttpResponseRedirect('/')
    
    if contest.initiator != request.user:
        # Только инициатор конкурса может выбрать победителя
        return HttpResponseRedirect('/')
    
    works = Work.objects.filter(contest=contest)
    if works.filter(id=winner_id).count() == 0:
        # Произведение-победитель не найдено
        return HttpResponseRedirect('/')
    
    for work in works:
        work.contest = None
        if work.id == winner_id:
            # Произведение-победитель
            rels = WorkRels.objects.get(work=work)
            if contest.for_exclusive:
                # Заказчик получает права на произведение
                work.owner = contest.initiator
                work.status = u'draft'
                rels.coauthors.clear()
                rels.trustee.clear()
            else:
                # Заказчик не получает права на произведение, но становится привелигированным читателем
                rels.trustee.add(contest.initiator)
            # Выплатить автору призовую сумму
            Transaction.objects.create_transaction(cash=contest.cash, detail=u'Приз за конкурс "%s"' % contest.title,
                                                   recipient=work.author, work=work)
            LrMessage.objects.create_message(work.author, title=u'Поздравляем с победой!',
                                             description=u'Поздравляем, вы победили в конкурсе <b>"%s"</b> с работой \
                                             <b>"%s"</b>! На ваш счет перечислено вознаграждение в сумме %.2f талантов. \
                                             Желаем вам дальнейших успехов!' % (contest.title, work.title, contest.cash))
            LrEvent.objects.create_event(render_to_string('events/finish_contest.html', { 'contest': contest, 'work': work }),
                                         u'Определен победитель Конкурса "%s"' % contest.title)
        work.save()
    
    contest.competitors.clear()
    contest.delete()
    return HttpResponseRedirect('board')


def get_comission(agree, request, contest):
    """ Принять или отвергнуть персональный заказ """
    if contest.competitors.filter(id=request.user.id).count() > 0:
        name = Profile.get_user_name(user=request.user, profile=request.profile)[0]
        if agree:
            work = Work.objects.createWork(author=request.user, title=contest.title, genre=contest.genre, contest=contest)
            contest.is_personal = False
            contest.save()
            LrMessage.objects.create_message(contest.initiator, title=u'Ваш заказ принят',
                                             description=u'С удовольствием сообщаем вам, что %s принял ваш заказ на \
                                             произведение <b>"%s"</b>.' % (name, contest.title))
            return HttpResponseRedirect('table?edit=%d' % work.id)
        else:
            Transaction.objects.create_transaction(cash=contest.cash, detail=u'Возврат призового фонда "%s"' % contest.title,
                                                   recipient=contest.initiator)
            contest.delete()
            LrMessage.objects.create_message(contest.initiator, title=u'Ваш заказ отклонен',
                                             description=u'С сожалением сообщаем вам, что %s отклонил ваш заказ на \
                                             произведение <b>"%s"</b>. Призовой фонд возвращен на ваш счет.' % (name, contest.title))
    return HttpResponseRedirect('board')
